package com.ay.smartpark.sdk.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;

import com.ay.smartpark.sdk.common.base.UploadFileBean;
import com.ay.smartpark.sdk.common.base.UploadFileResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class UploadFileUtils {

    private static final Logger logger = LoggerFactory.getLogger(UploadFileUtils.class);

    public static UploadFileResponse uploadFiles(UploadFileBean uploadFileBean) {
        //判断上传参数
        if (StringUtils.isBlank(uploadFileBean.getWebProtocol())) {
            return UploadFileResponse.fail("上传文件参数有误");
        }
        if (StringUtils.isBlank(uploadFileBean.getWebDomain())) {
            return UploadFileResponse.fail("上传文件参数有误");
        }
        if (StringUtils.isBlank(uploadFileBean.getTableId())) {
            return UploadFileResponse.fail("上传文件参数有误");
        }
        if (StringUtils.isBlank(uploadFileBean.getFieldId())) {
            return UploadFileResponse.fail("上传文件参数有误");
        }
        if (StringUtils.isBlank(uploadFileBean.getRecordId())) {
            return UploadFileResponse.fail("上传文件参数有误");
        }
        if (StringUtils.isBlank(uploadFileBean.getPhpSessionId())) {
            return UploadFileResponse.fail("上传文件参数有误");
        }
        List<File> fileList = uploadFileBean.getFiles();
        for (File file : fileList) {
            if (!file.exists()) {
                return UploadFileResponse.fail("上传文件参数有误");
            }
        }

        List<String> resultData = new ArrayList<>();
        int total = fileList.size();
        int max = 5;
        //判断上传文件个数是否大于最大上传个数
        if (total > max) {
            //count为上传次数
            int count = (total % max == 0) ? (total / max) : (total / max + 1);
            int start = 0;
            int end = max;
            //分count次上传文件
            for (int i = 0; i < count; i++) {
                List<File> subUploadFiles = fileList.subList(start, end);
                start = start + max;
                end = (end > total) ? (total) : (start + max);
                UploadFileBean subUploadFileBean = buildSubUploadFileBean(subUploadFiles, uploadFileBean);
                //上传文件返回结果
                UploadFileResponse uploadFileResponse = uploadFilesByPlatform(subUploadFileBean);
                //判断上传过程中是否出错
                if (uploadFileResponse.getError() != null && uploadFileResponse.getError().length() != 0) {
                    return uploadFileResponse;
                }
                resultData.addAll(uploadFileResponse.getData());
            }
        } else {
            UploadFileResponse uploadFileResponse = uploadFilesByPlatform(uploadFileBean);
            resultData = uploadFileResponse.getData();
        }
        if (resultData != null && resultData.size() == total) {
            List<String> decryptData = new ArrayList<>();
            //对从平台获取的图片文件解密
            for (String resultName : resultData) {
                decryptData.add(EncryptUtils.attachDecrypt(resultName));
            }
            return UploadFileResponse.success(decryptData);
        } else {
            return UploadFileResponse.fail("上传文件丢失文件");
        }
    }

    private static UploadFileResponse uploadFilesByPlatform(UploadFileBean uploadFileBean) {
        List<String> resultData = new ArrayList<>();

        List<File> fileList = uploadFileBean.getFiles();
        String postUrl = buildUploadFileUrl(uploadFileBean);
        String phpSessionId = uploadFileBean.getPhpSessionId();
        String recordIdStr = uploadFileBean.getRecordId();
        //普通字段重新设置了编码方式
        StringBody recordId = new StringBody(recordIdStr, ContentType.create("text/plain", Consts.UTF_8));

        CloseableHttpClient httpclient = HttpClients.createDefault();
        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
        CloseableHttpResponse response = null;
        HttpEntity responseEntity;

        try {
            HttpPost httpPost = new HttpPost(postUrl);
            //设置recordid
            multipartEntityBuilder.addPart("recordid", recordId);
            //设置Filedata[]
            for (File file : fileList) {
                FileBody fileBody = new FileBody(file);
                multipartEntityBuilder.addPart("Filedata[]", fileBody);
            }
            HttpEntity httpEntity = multipartEntityBuilder.build();
            httpPost.setEntity(httpEntity);
            //设置header
            httpPost.setHeader("Accept", "application/json");
            httpPost.setHeader("Cookie", "PHPSESSID=" + phpSessionId);
            //执行请求
            response = httpclient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK) {
                responseEntity = response.getEntity();
                if (responseEntity != null) {
                    String responseStr = EntityUtils.toString(responseEntity, Charset.forName("UTF-8"));
                    //打印响应内容
                    Map resultMaps = (Map) JSON.parse(responseStr);
                    JSONArray jsonArray = (JSONArray) resultMaps.get("result");
                    resultData = jsonArray.toJavaList(String.class);
                }
            }
        } catch (Exception e) {
            logger.error("uploadFilesByPlatform error", e);
            return UploadFileResponse.fail(e.getMessage());
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    logger.error("response close error", e);
                }
            }
            if (httpclient != null) {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    logger.error("httpclient close error", e);
                }
            }
        }
        return UploadFileResponse.success(resultData);
    }


    private static UploadFileBean buildSubUploadFileBean(List<File> subUploadFiles, UploadFileBean uploadFileBean) {
        UploadFileBean subUploadFileBean = new UploadFileBean();
        subUploadFileBean.setWebProtocol(uploadFileBean.getWebProtocol());
        subUploadFileBean.setWebDomain(uploadFileBean.getWebDomain());
        subUploadFileBean.setTableId(uploadFileBean.getTableId());
        subUploadFileBean.setFieldId(uploadFileBean.getFieldId());
        subUploadFileBean.setRecordId(uploadFileBean.getRecordId());
        subUploadFileBean.setPhpSessionId(uploadFileBean.getPhpSessionId());
        subUploadFileBean.setFiles(subUploadFiles);
        return subUploadFileBean;
    }

    private static String buildUploadFileUrl(UploadFileBean uploadFileBean) {
        StringBuilder builder = new StringBuilder();
        builder.append(uploadFileBean.getWebProtocol());
        builder.append(uploadFileBean.getWebDomain());
        builder.append("/api/datacenter/attach/upload/");
        builder.append(0);
        builder.append(File.separator);
        builder.append(uploadFileBean.getTableId());
        builder.append(File.separator);
        builder.append(uploadFileBean.getFieldId());
        return builder.toString();
    }

    public static JSONArray getFuJianJsonArray(List<String> fileNameList) {
        JSONArray jsonArray = new JSONArray();
        if (fileNameList != null && !fileNameList.isEmpty()) {
            for (String fileName : fileNameList) {
                jsonArray.add(fileName);
            }
        }
        return jsonArray;
    }

    public static void deleteFile(List<File> files) {
        for (File file : files) {
            if (file.exists()) {
                file.delete();
            }
        }
    }
}
